package generator;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSON;
import generator.engine.GeneralEngine;
import generator.engine.impl.DefaultEngine;
import generator.engine.parse.ClassInfoParser;
import generator.entity.ClassInfo;
import generator.util.DatabaseUtil;
import generator.util.GenConfig;
import generator.util.IOTool;
import generator.util.StringUtils;
import generator.util.TableParseUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
import javax.swing.JButton;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JCheckBox;
import javax.swing.JTextArea;
import javax.swing.JScrollBar;

/**
 * @author chengsp
 * @date 2019-09-25 12:40
 */
public class MainWin {
    private final static Logger logger = LoggerFactory.getLogger(MainWin.class);
    private JFrame frame;
    private JTextField urlTextField;
    private JTextField userTextField;
    private JPasswordField passwordTextField;
    private JTextField packageTextField;
    private JTextField projectNameTextField;
    private JTextField authorTextField;
    private GenConfig genConfig;
    private JTextField driverNameTextField;
    private GeneralEngine generalEngine;
    private JTextField batchTableNameTextField;
    private JTextField returnObjectTextField;
    private ClassInfoParser classInfoParser;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    MainWin window = new MainWin();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public MainWin() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        String content = "";
        File file = new File("config.json");
        if (file.exists()) {
            content = IoUtil.read(FileUtil.getReader(file, "UTF-8"));
            genConfig = JSON.parseObject(content, GenConfig.class);
        } else {
            genConfig = new GenConfig();
        }
        genConfig.getClassInfoList().clear();
        generalEngine = new DefaultEngine(genConfig);
        frame = new JFrame();
        frame.setVisible(true);
        frame.setBounds(100, 100, 821, 761);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);
        frame.setResizable(false);
        JPanel dbPanel = new JPanel();
        dbPanel.setBounds(14, 13, 775, 168);
        frame.getContentPane().add(dbPanel);
        dbPanel.setLayout(null);

        JLabel dbTypeLabel = new JLabel("数据库类型");
        dbTypeLabel.setBounds(14, 13, 83, 34);
        dbPanel.add(dbTypeLabel);

        JComboBox<String> dbTypeComboBox = new JComboBox<>();
        dbTypeComboBox.addItemListener(e -> {
            String dbType = e.getItem().toString();
            genConfig.setDbType(dbType);
        });
        dbTypeComboBox.setBounds(111, 18, 83, 24);
        dbPanel.add(dbTypeComboBox);
        dbTypeComboBox.setModel(new DefaultComboBoxModel<>(new String[]{"mysql", "oracle", "pgsql", "sqlserver"}));

        JLabel urlLabel = new JLabel("url");
        urlLabel.setBounds(266, 13, 72, 34);
        dbPanel.add(urlLabel);

        urlTextField = new JTextField();
        urlTextField.setBounds(365, 18, 396, 24);
        dbPanel.add(urlTextField);
        urlTextField.setColumns(10);

        JLabel dbNameLabel = new JLabel("数据库");
        dbNameLabel.setBounds(14, 75, 72, 18);
        dbPanel.add(dbNameLabel);

        JTextField dbNameTextField = new JTextField();
        dbNameTextField.setBounds(108, 72, 86, 24);
        dbPanel.add(dbNameTextField);
        dbNameTextField.setColumns(10);

        JLabel userLabel = new JLabel("用户名");
        userLabel.setBounds(266, 75, 72, 18);
        dbPanel.add(userLabel);

        userTextField = new JTextField();
        userTextField.setBounds(365, 72, 117, 24);
        dbPanel.add(userTextField);
        userTextField.setColumns(10);

        JLabel label = new JLabel("密码");
        label.setBounds(14, 121, 72, 18);
        dbPanel.add(label);

        passwordTextField = new JPasswordField();
        passwordTextField.setBounds(111, 118, 216, 24);
        dbPanel.add(passwordTextField);

        JLabel driverNameLabel = new JLabel("驱动");
        driverNameLabel.setBounds(360, 121, 72, 18);
        dbPanel.add(driverNameLabel);

        driverNameTextField = new JTextField();
        driverNameTextField.setBounds(435, 118, 230, 24);
        dbPanel.add(driverNameTextField);
        driverNameTextField.setColumns(10);

        JLabel overrideLabel = new JLabel("是否覆盖");
        overrideLabel.setBounds(508, 75, 72, 18);
        dbPanel.add(overrideLabel);

        JCheckBox overrideCheckBox = new JCheckBox("否");
        overrideCheckBox.setBounds(603, 71, 133, 27);
        dbPanel.add(overrideCheckBox);

        JPanel configPanel = new JPanel();
        configPanel.setBounds(14, 194, 775, 218);
        frame.getContentPane().add(configPanel);
        configPanel.setLayout(null);

        JLabel rootPathLabel = new JLabel("生成路径");
        rootPathLabel.setBounds(14, 13, 72, 18);
        configPanel.add(rootPathLabel);

        JButton rootPathButton = new JButton("选择路径");
        rootPathButton.addActionListener(e -> {
            JFileChooser fileChooser = new JFileChooser(new File("."));
            fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            int result = fileChooser.showOpenDialog(frame);
            if (result == JFileChooser.APPROVE_OPTION) {
                genConfig.setRootPath(fileChooser.getSelectedFile().getAbsolutePath());
                logger.info("rootPath:{}", genConfig.getRootPath());
            }

        });
        rootPathButton.setBounds(109, 9, 113, 27);
        configPanel.add(rootPathButton);

        JLabel packageLabel = new JLabel("包前缀");
        packageLabel.setBounds(389, 13, 72, 18);
        configPanel.add(packageLabel);

        packageTextField = new JTextField();
        packageTextField.setBounds(489, 10, 226, 24);
        configPanel.add(packageTextField);
        packageTextField.setColumns(10);

        JLabel projectNameLabel = new JLabel("工程名称");
        projectNameLabel.setBounds(14, 71, 72, 18);
        configPanel.add(projectNameLabel);

        projectNameTextField = new JTextField();
        projectNameTextField.setBounds(109, 68, 239, 24);
        configPanel.add(projectNameTextField);
        projectNameTextField.setColumns(10);

        JLabel authorLabel = new JLabel("作者");
        authorLabel.setBounds(389, 68, 72, 18);
        configPanel.add(authorLabel);

        authorTextField = new JTextField();
        authorTextField.setBounds(489, 68, 226, 24);
        configPanel.add(authorTextField);
        authorTextField.setColumns(10);

        JLabel batchTableNameLabel = new JLabel("批量表名");
        batchTableNameLabel.setBounds(14, 123, 72, 18);
        configPanel.add(batchTableNameLabel);

        batchTableNameTextField = new JTextField();
        batchTableNameTextField.setBounds(109, 120, 606, 24);
        configPanel.add(batchTableNameTextField);
        batchTableNameTextField.setColumns(10);

        JLabel returnObjectLabel = new JLabel("控制层返回实体名");
        returnObjectLabel.setBounds(14, 172, 135, 18);
        configPanel.add(returnObjectLabel);

        returnObjectTextField = new JTextField();
        returnObjectTextField.setBounds(179, 169, 135, 24);
        configPanel.add(returnObjectTextField);
        returnObjectTextField.setColumns(10);

        JLabel parseTypeLabel = new JLabel("解析类型");
        parseTypeLabel.setBounds(361, 172, 72, 18);
        configPanel.add(parseTypeLabel);

        JComboBox<String> parseTypeComboBox = new JComboBox<>();
        parseTypeComboBox.setModel(new DefaultComboBoxModel<>(new String[]{"tableSql", "jdbc"}));
        parseTypeComboBox.setBounds(466, 169, 91, 24);
        configPanel.add(parseTypeComboBox);

        JLabel tableSqlLabel = new JLabel("建表sql");
        tableSqlLabel.setBounds(14, 425, 72, 18);
        frame.getContentPane().add(tableSqlLabel);

        JTextArea tableSqlTextArea = new JTextArea();
        tableSqlTextArea.setBounds(14, 456, 775, 180);
        frame.getContentPane().add(tableSqlTextArea);

        JButton genButton = new JButton("开始生成");
        genButton.setBounds(657, 649, 144, 64);
        frame.getContentPane().add(genButton);
        genButton.addActionListener(e -> {
            genConfig.setPassword(new String(passwordTextField.getPassword()));
            genConfig.setAuthorName(authorTextField.getText());
            genConfig.setPackageName(packageTextField.getText());
            genConfig.setProjectName(projectNameTextField.getText());
            genConfig.setDriverName(driverNameTextField.getText());
            genConfig.setUrl(urlTextField.getText());
            genConfig.setUser(userTextField.getText());
            genConfig.setDbName(dbNameTextField.getText());
            genConfig.setTableNames(batchTableNameTextField.getText().split(","));
            genConfig.setOverride(overrideCheckBox.isSelected());
            genConfig.setResultName(returnObjectTextField.getText());
            Object selectedItem = parseTypeComboBox.getSelectedItem();
            if ("jdbc".equals(selectedItem)) {
                try {
                    String tableNames = batchTableNameTextField.getText();
                    logger.info(tableNames);
                    List<String> rows = Arrays.asList(JSON.toJSONString(genConfig));
                    IOTool.writeLine("config.json", rows);
                    IOTool.writeLine("config" + new SimpleDateFormat("yyyyMMddhhmmss").format(new Date()) + ".json", rows);
                    List<ClassInfo> classInfoList = genConfig.getClassInfoList();
                    for (String table : genConfig.getTableNames()) {
                        ClassInfo classInfo = DatabaseUtil.parseClassInfo(table, genConfig);
                        classInfoList.add(classInfo);
                    }
                    genConfig.setClassInfoList(classInfoList);
                    for (ClassInfo classInfo : classInfoList) {
                        generalEngine.execute(classInfo);
                    }
                    classInfoList.clear();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            } else {
                try {
                    ClassInfo classInfo = TableParseUtil.processTableIntoClassInfo(tableSqlTextArea.getText());
                    generalEngine.execute(classInfo);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }


        });
        if (content.length() > 0) {
            dbTypeComboBox.setSelectedItem(genConfig.getDbType());
            urlTextField.setText(genConfig.getUrl());
            dbNameTextField.setText(genConfig.getDbName());
            userTextField.setText(genConfig.getUser());
            passwordTextField.setText(genConfig.getPassword());
            packageTextField.setText(genConfig.getPackageName());
            projectNameTextField.setText(genConfig.getProjectName());
            authorTextField.setText(genConfig.getAuthorName());
            batchTableNameTextField.setText(StringUtils.join(",", genConfig.getTableNames()));
            returnObjectTextField.setText(genConfig.getResultName());
        }
    }
}
